#include <cstdio>
#include <cstring>

#include <algorithm>

using namespace std;

const int MAX_V = 20000;
const int MAX_EDGES = 10000000;
const int INF = 1000000;

int n, m, D, W;
int x[55], y[55], c[55];

int v, source, sink; // feasible
bool can[55][55];
bool reach[55];

int vp, ep, superSrc, src, dest; // optimal answer
int head[MAX_V];
int endpoint[MAX_EDGES], next[MAX_EDGES], C[MAX_EDGES];

void dfs( int x )
{
	if( 0 <= x && x < n && c[x] == 0 ) {
		reach[x] = false;
		return;
	}
	reach[x] = true;
	for( int y = 0; y < v; ++y )
		if( can[x][y] && !reach[y] ) dfs(y);
}

void add( int u, int v, int _C )
{
	endpoint[ep] = v, C[ep] = _C, next[ep] = head[u];
	head[u] = ep++;

	endpoint[ep] = u, C[ep] = 0, next[ep] = head[v];
	head[v] = ep++;
}

int queue[MAX_V], front, back;
int prev[MAX_V], by[MAX_V];

int bfs( void )
{
	front = back = 0;
	queue[back++] = superSrc;

	memset(prev, -1, sizeof(prev));
	prev[superSrc] = superSrc;

	for( ; front < back; ++front ) {
		int u = queue[front];

		for( int i = head[u]; i >= 0; i = next[i] )
			if( C[i] && prev[endpoint[i]] < 0 ) {
				queue[back++] = endpoint[i];
				prev[endpoint[i]] = u;
				by[endpoint[i]] = i;
			}
	}
	if( prev[dest] < 0 ) return 0;

	int inc = INF;

	for( int u = dest; u != superSrc; ) {
		inc = min(inc, C[by[u]]);
		u = prev[u];
	}
	for( int u = dest; u != superSrc; ) {
		C[by[u]] -= inc;
		C[by[u] ^ 1] += inc;
		u = prev[u];
	}

	return inc;
}

int main( void )
{
	freopen( "input.txt", "r", stdin );

	scanf( "%d %d %d %d", &n, &m, &D, &W );
	for( int i = 0; i < n; ++i )
		scanf( "%d %d %d", &x[i], &y[i], &c[i] );

	v = n+2; source = n, sink = n+1;
	for( int i = 0; i < n; ++i ) {
		if( y[i] <= D ) can[source][i] = can[i][source] = true;
		if( y[i]+D >= W ) can[i][sink] = can[sink][i] = true;
	}
	if( W <= D ) can[source][sink] = true;
	for( int i = 0; i < n; ++i )
		for( int j = 0; j < n; ++j ) {
			int dx = x[i]-x[j]; if( dx < 0 ) dx = -dx;
			int dy = y[i]-y[j]; if( dy < 0 ) dy = -dy;
			if( dx*dx + dy*dy <= D*D ) can[i][j] = can[j][i] = true;
		}

	dfs(source);
	if( !reach[sink] ) {
		printf( "IMPOSSIBLE\n" );
		return 0;
	}
	if( can[source][sink] ) {
		printf( "1\n" );
		return 0;
	}

	vp = 3; superSrc = 0, src = 1, dest = 2;
	memset(head, -1, sizeof(head));

	add(superSrc, src, m);

	int total = 0;

	for( int maxLevel = 0; ; ++maxLevel ) {
		int curLevel[55];

		for( int i = 0; i < n; ++i ) {
			curLevel[i] = 3 + maxLevel*2*n + 2*i;
			add(curLevel[i], curLevel[i]+1, c[i]);
		}
		vp += 2*n;

		for( int i = 0; i < n; ++i ) {
			if( can[source][i] ) add(src, curLevel[i], INF);
			if( can[i][sink] ) add(curLevel[i]+1, dest, INF);
		}
		if( maxLevel ) {
			for( int i = 0; i < n; ++i )
				for( int j = 0; j < n; ++j )
					if( can[i][j] ) add(curLevel[i]-2*n+1, curLevel[j], INF);
		}

		int by = bfs();
		while( by ) {
			total += by;
			by = bfs();
		}

//		printf( "total = %d\n", total );

		if( total == m ) {
			printf( "%d\n", maxLevel+2 );
			break;
		}
	}

	return 0;
}
